parameters:
  buildConfig: ''
  nameSuffix: ''
  buildArgs: ''
  archType: ''
  hostedOs: ''
  osGroup: ''
  osSubgroup: ''
  container: ''
  crossBuild: false
  variables: []
  targetRid: ''
  timeoutInMinutes: ''
  dependsOn: []
  pool: ''
  platform: ''
  condition: true
  useContinueOnErrorDuringBuild: false
  shouldContinueOnError: false
  isOfficialBuild: false
  isSourceBuild: false
  isNonPortableSourceBuild: false
  runtimeFlavor: 'coreclr'
  runtimeVariant: ''
  helixQueues: ''
  enablePublishTestResults: false
  testResultsFormat: ''
  postBuildSteps: []
  extraVariablesTemplates: []
  isManualCodeQLBuild: false
  preBuildSteps: []
  enableRichCodeNavigation: false
  richCodeNavigationLanguage: 'csharp'
  disableComponentGovernance: ''

jobs:
- template: /eng/common/templates/job/job.yml
  parameters:
    ${{ if eq(parameters.hostedOs, '') }}:
      name: ${{ format('build_{0}{1}_{2}_{3}_{4}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix) }}
      displayName: ${{ format('{0}{1}-{2} {3} {4} {5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig, parameters.nameSuffix, parameters.runtimeVariant) }}
    ${{ if ne(parameters.hostedOs, '') }}:
      name: ${{ format('build_{0}{1}_{2}_{3}_{4}_{5}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.hostedOs, parameters.buildConfig, parameters.nameSuffix) }}
      displayName: ${{ format('{0}{1}-{2} {3} {4} {5} {6}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.hostedOs, parameters.buildConfig, parameters.nameSuffix, parameters.runtimeVariant) }}
    pool: ${{ parameters.pool }}
    container: ${{ parameters.container }}
    condition: and(succeeded(), ${{ parameters.condition }})
    timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
    enablePublishTestResults: ${{ parameters.enablePublishTestResults }}
    testResultsFormat: ${{ parameters.testResultsFormat }}

    enableRichCodeNavigation: ${{ parameters.enableRichCodeNavigation }}
    richCodeNavigationLanguage: ${{ parameters.richCodeNavigationLanguage }}

    # Component governance does not work on musl machines
    ${{ if eq(parameters.osSubGroup, '_musl') }}:
      disableComponentGovernance: true
    ${{ else }}:
      disableComponentGovernance: ${{ parameters.disableComponentGovernance }}

    workspace:
      clean: all

    ${{ if ne(parameters.dependsOn,'') }}:
      dependsOn: ${{ parameters.dependsOn }}

    variables:
      - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
          - group: DotNet-HelixApi-Access
          - group: AzureDevOps-Artifact-Feeds-Pats

      - name: _osParameter
        value: -os ${{ parameters.osGroup }}
      - name: _archParameter
        value: -arch ${{ parameters.archType }}

      - ${{ if and(eq(parameters.osGroup, 'linux'), eq(parameters.osSubGroup, '_bionic')) }}:
        - name: _osParameter
          value: -os linux-bionic

      - name: crossArg
        value: ''
      - ${{ if eq(parameters.crossBuild, true) }}:
        - name: crossArg
          value: '-cross'

      - ${{ if ne(parameters.jobParameters.crossrootfsDir, '') }}:
        # This is only required for cross builds.
        - name: ROOTFS_DIR
          value: ${{ parameters.jobParameters.crossrootfsDir }}

      - name: _officialBuildParameter
        ${{ if eq(parameters.isOfficialBuild, true) }}:
          value: /p:OfficialBuildId=$(Build.BuildNumber)
        ${{ if ne(parameters.isOfficialBuild, true) }}:
          value: ''

      - name: _buildDarwinFrameworksParameter
        ${{ if in(parameters.osGroup, 'ios', 'tvos', 'maccatalyst')}}:
          value: /p:BuildDarwinFrameworks=true
        ${{ if notin(parameters.osGroup, 'ios', 'tvos', 'maccatalyst')}}:
          value: ''

      # Set no native sanitizers by default
      - name: _nativeSanitizersArg
        value: ''

      - ${{ each variableTemplate in parameters.extraVariablesTemplates }}:
        - template: ${{ variableTemplate.template }}
          parameters:
            osGroup: ${{ parameters.osGroup }}
            osSubgroup: ${{ parameters.osSubgroup }}
            archType: ${{ parameters.archType }}
            buildConfig: ${{ parameters.buildConfig }}
            runtimeFlavor: ${{ parameters.runtimeFlavor }}
            runtimeVariant: ${{ parameters.runtimeVariant }}
            helixQueues: ${{ parameters.helixQueues }}
            targetRid: ${{ parameters.targetRid }}
            nameSuffix: ${{ parameters.nameSuffix }}
            platform: ${{ parameters.platform }}
            shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
            ${{ if ne(variableTemplate.forwardedParameters, '') }}:
              ${{ each parameter in variableTemplate.forwardedParameters }}:
                ${{ parameter }}: ${{ parameters[parameter] }}
            ${{ if ne(variableTemplate.parameters, '') }}:
              ${{ insert }}: ${{ variableTemplate.parameters }}

      - ${{ each variable in parameters.variables }}:
        - ${{ variable }}
    steps:
    - ${{ if eq(parameters.osGroup, 'windows') }}:
      - template: /eng/pipelines/common/templates/disable-vsupdate-or-failfast.yml

    - checkout: self
      clean: true
      # If running in source build mode, a git stash will be used for the inner clone. Avoid setting a fetch depth,
      # as a stash of a shallow cloned repo is not currently supported.
      ${{ if ne(parameters.isSourceBuild, true) }}:
        fetchDepth: $(checkoutFetchDepth)

    - ${{ if and(eq(parameters.isOfficialBuild, true), notin(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator')) }}:
      - template: /eng/pipelines/common/restore-internal-tools.yml

    - ${{ if ne(variables['System.TeamProject'], 'public') }}:
      - ${{ if and(ne(parameters.osGroup, 'windows'), ne(parameters.hostedOs, 'windows')) }}:
        - task: Bash@3
          displayName: Setup Private Feeds Credentials
          inputs:
            filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh
            arguments: $(Build.SourcesDirectory)/NuGet.config $Token
          env:
            Token: $(dn-bot-dnceng-artifact-feeds-rw)
      - ${{ else }}:
        - task: PowerShell@2
          displayName: Setup Private Feeds Credentials
          inputs:
            filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
            arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
          env:
            Token: $(dn-bot-dnceng-artifact-feeds-rw)

    - ${{ each monoCrossAOTTargetOS in parameters.monoCrossAOTTargetOS }}:
      - task: DownloadPipelineArtifact@2
        displayName: Download ${{monoCrossAOTTargetOS}} AOT offset files
        inputs:
          artifact: Mono_Offsets_${{monoCrossAOTTargetOS}}
          path: '$(Build.SourcesDirectory)/artifacts/obj/mono/offsetfiles'

    - ${{ if eq(parameters.isSourceBuild, true) }}:
      - template: /eng/common/templates/steps/source-build.yml
        parameters:
          platform:
            baseOS: ${{ parameters.baseOS }}
            buildScript: $(Build.SourcesDirectory)$(dir)build$(scriptExt)
            nonPortable: ${{ parameters.isNonPortableSourceBuild }}
            targetRID: ${{ parameters.targetRid }}
            name: ${{ parameters.platform }}

    - ${{ if in(parameters.osGroup, 'osx', 'maccatalyst', 'ios', 'iossimulator', 'tvos', 'tvossimulator') }}:
      - script: $(Build.SourcesDirectory)/eng/install-native-dependencies.sh ${{ parameters.osGroup }}
        displayName: Install Build Dependencies

      - script: |
          du -sh $(Build.SourcesDirectory)/*
          df -h
        displayName: Disk Usage before Build

    - ${{ if in(parameters.platform, 'browser_wasm_win', 'wasi_wasm_win') }}:
      # Update machine certs
      - task: PowerShell@2
        displayName: Update machine certs
        inputs:
          filePath: $(Build.SourcesDirectory)/eng/pipelines/mono/update-machine-certs.ps1

    - ${{ if ne(parameters.preBuildSteps,'') }}:
      - ${{ each preBuildStep in parameters.preBuildSteps }}:
        - ${{ if ne(preBuildStep.template, '') }}:
          - template: ${{ preBuildStep.template }}
            parameters:
              osGroup: ${{ parameters.osGroup }}
              osSubgroup: ${{ parameters.osSubgroup }}
              archType: ${{ parameters.archType }}
              buildConfig: ${{ parameters.buildConfig }}
              runtimeFlavor: ${{ parameters.runtimeFlavor }}
              runtimeVariant: ${{ parameters.runtimeVariant }}
              helixQueues: ${{ parameters.helixQueues }}
              targetRid: ${{ parameters.targetRid }}
              nameSuffix: ${{ parameters.nameSuffix }}
              platform: ${{ parameters.platform }}
              pgoType: ${{ parameters.pgoType }}
              shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
              ${{ if ne(preBuildStep.forwardedParameters, '') }}:
                ${{ each parameter in preBuildStep.forwardedParameters }}:
                  ${{ parameter }}: ${{ parameters[parameter] }}
              ${{ if ne(preBuildStep.parameters, '') }}:
                ${{ insert }}: ${{ preBuildStep.parameters }}
        - ${{ else }}:
          - ${{ preBuildStep }}

    # Build
    - ${{ if eq(parameters.isSourceBuild, false) }}:
      - ${{ if eq(parameters.isManualCodeQLBuild, true) }}:
        - task: CodeQL3000Init@0
          displayName: Initialize CodeQL (manually-injected)

      - template: /eng/pipelines/common/templates/global-build-step.yml
        parameters:
          buildArgs: ${{ parameters.buildArgs }}
          useContinueOnErrorDuringBuild: ${{ parameters.useContinueOnErrorDuringBuild }}
          shouldContinueOnError: ${{ parameters.shouldContinueOnError }}

      - ${{ if eq(parameters.isManualCodeQLBuild, true) }}:
        - task: CodeQL3000Finalize@0
          displayName: Finalize CodeQL (manually-injected)
    #endif isSourceBuild

    - ${{ if in(parameters.osGroup, 'osx', 'ios', 'tvos', 'android') }}:
      - script: |
          du -sh $(Build.SourcesDirectory)/*
          df -h
        displayName: Disk Usage after Build
        condition: always()

      # If intended to send extra steps after regular build add them here.
    - ${{ if ne(parameters.postBuildSteps,'') }}:
      - ${{ each postBuildStep in parameters.postBuildSteps }}:
        - ${{ if ne(postBuildStep.template, '') }}:
          - template: ${{ postBuildStep.template }}
            parameters:
              osGroup: ${{ parameters.osGroup }}
              osSubgroup: ${{ parameters.osSubgroup }}
              archType: ${{ parameters.archType }}
              buildConfig: ${{ parameters.buildConfig }}
              runtimeFlavor: ${{ parameters.runtimeFlavor }}
              runtimeVariant: ${{ parameters.runtimeVariant }}
              helixQueues: ${{ parameters.helixQueues }}
              targetRid: ${{ parameters.targetRid }}
              nameSuffix: ${{ parameters.nameSuffix }}
              platform: ${{ parameters.platform }}
              shouldContinueOnError: ${{ parameters.shouldContinueOnError }}
              ${{ if ne(postBuildStep.forwardedParameters, '') }}:
                ${{ each parameter in postBuildStep.forwardedParameters }}:
                  ${{ parameter }}: ${{ parameters[parameter] }}
              ${{ if ne(postBuildStep.parameters, '') }}:
                ${{ insert }}: ${{ postBuildStep.parameters }}
        - ${{ else }}:
          - ${{ postBuildStep }}

      - ${{ if and(eq(parameters.isOfficialBuild, true), eq(parameters.osGroup, 'windows')) }}:
        - powershell: ./eng/collect_vsinfo.ps1 -ArchiveRunName postbuild_log
          displayName: Collect vslogs on exit
          condition: always()

    - task: PublishBuildArtifacts@1
      displayName: Publish Logs
      inputs:
        PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/'
        PublishLocation: Container
        ${{ if notin(parameters.osGroup, 'browser', 'wasi') }}:
          ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.osSubGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }}
        ${{ if in(parameters.osGroup, 'browser', 'wasi') }}:
          ArtifactName: Logs_Build_Attempt$(System.JobAttempt)_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.hostedOs }}_${{ parameters.buildConfig }}_${{ parameters.nameSuffix }}
      continueOnError: true
      condition: always()
